package com.hoangqp.lookdict;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.hoangqp.android.database.Book;
import com.hoangqp.android.database.DatabaseHandler;
import com.hoangqp.util.CaculateScreenSize;
import com.hoangqp.util.ExternalStorage;
import com.hoangqp.util.ThreadUpdateBook;
import com.hoangqp.util.Utils;

import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

public class CategoryActivity extends Activity implements
		ActionBar.OnNavigationListener {

	private static final String DIRECTORY_DATA = "LookDict_Data";
	private static final String PATH_FILE = "PATH_FILE";
	
	// Refresh menu item
	private MenuItem refreshMenuItem;

	private LayoutInflater inflater = null;

	// Database
	private DatabaseHandler dataBaseHandler;
	
	private static int countNewBooks;

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.category_menu, menu);

		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case R.id.refresh_book:
			// refresh
			refreshMenuItem = item;
			// load the data from server
			new SyncData().execute();
			// setRefreshActionButtonState(true);
			return true;

		case R.id.share_app:
				Intent i = new Intent(getApplicationContext(),
						ShareAppActivity.class);
				startActivity(i);
				// showPopupShareApp(TOPActivity.this);
				return true;
				
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	private static final int NUM_ROW_IN_TABLE = 5;
	// Height Status Bar
	private static final int LOW_DPI_STATUS_BAR_HEIGHT = 19;
	private static final int MEDIUM_DPI_STATUS_BAR_HEIGHT = 25;
	private static final int HIGH_DPI_STATUS_BAR_HEIGHT = 38;

	private ActionBar actionBar;
	private TableLayout tblCategoryLayout;

	private List<Book> files = new ArrayList<Book>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.category_activity);

		actionBar = getActionBar();

		tblCategoryLayout = (TableLayout) findViewById(R.id.tblCategoryLayout);

		inflater = (LayoutInflater) getApplicationContext().getSystemService(
				Context.LAYOUT_INFLATER_SERVICE);

		dataBaseHandler = new DatabaseHandler(this);

		// make directory in external sdcard
		makeDirectoryOnExternalSDCard();
	
		// save book into database
		storeAllBooks();

		// get all book in database
		files = dataBaseHandler.getAllBooks();

		// UI
		//createBookUI();
		//addElement(files.size());
	}

	/**
	 * create UI book shelf
	 */
	private void createBookUI() {
		LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT);

		for (int i = 0; i < NUM_ROW_IN_TABLE; i++) {

			HorizontalScrollView hsv = new HorizontalScrollView(this);
			LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
					LayoutParams.WRAP_CONTENT);
			params.height = (sizeOfScreen().heightScreen()
					- actionBar.getHeight() - heightStatusBar())
					/ NUM_ROW_IN_TABLE - convertDpToPixel(getRowPaddingValue());
			hsv.setLayoutParams(params);

			if (i == 0)
				hsv.setBackgroundResource(R.drawable.book_shelf_empty);
			else
				hsv.setBackgroundResource(R.drawable.book_shelf_empty_01);

			TableRow tblRow = new TableRow(this);
			tblRow.setLayoutParams(layoutParams);
			tblRow.setGravity(Gravity.BOTTOM);

			hsv.addView(tblRow);
			tblCategoryLayout.addView(hsv, i);
		}

	}

	private void addElement(int numBook) {
		int rowBook = 0;
		int currentBook = 0;
		if (numBook % 4 == 0) {
			rowBook = numBook / 4;
			currentBook = 4;
		} else {
			rowBook = numBook / 4 + 1;
			currentBook = numBook % 4;
		}

		for (int i = 0; i < rowBook; i++) {
			HorizontalScrollView hsv = (HorizontalScrollView) tblCategoryLayout
					.getChildAt(i);
			TableRow tableRow = (TableRow) hsv.getChildAt(0);

			if (i == (rowBook - 1)) {
				for (int numElement = 0; numElement < currentBook; numElement++) {
					addElementToTableRow(tableRow, numElement, i);
				}
			} else {
				for (int numElement = 0; numElement < 4; numElement++) {
					addElementToTableRow(tableRow, numElement, i);
				}
			}
		}
	}

	private void addElementToTableRow(TableRow tableRow, final int position,
			final int numRow) {

		TableRow.LayoutParams params = new TableRow.LayoutParams(sizeOfScreen()
				.widthScreen() / 4, TableRow.LayoutParams.WRAP_CONTENT);
		final int pos = getpositionItemOnList(numRow, position);
		final Book f = files.get(pos);

		View layout = inflater.inflate(R.layout.book_dictionary, null);
		layout.setLayoutParams(params);

		TextView txtView = (TextView) layout.findViewById(R.id.book_name);
		txtView.setText(f.get_name());

		final ImageView imgView = (ImageView) layout.findViewById(R.id.img_new_book);
		if(f.is_isRead()){
			imgView.setVisibility(View.GONE);
		}
		
		ImageButton imageBtn = (ImageButton) layout
				.findViewById(R.id.img_btn_book);
		imageBtn.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Runnable runnable = new ThreadUpdateBook(f, dataBaseHandler);
				new Thread(runnable).start();
				
				runOnUiThread(new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						imgView.setVisibility(View.GONE);
					}
				});
				
				Intent intent = new Intent(getApplicationContext(),
						MainActivity.class);
				Utils.PATH_FILE_VALUE = f.get_path();
				intent.putExtra(PATH_FILE, f.get_path());
				startActivity(intent);
			}
		});

		tableRow.addView(layout, position);
	}

	private int getpositionItemOnList(int numRow, int element) {
		if (numRow == 0)
			return element;
		else if (numRow == 1)
			return 3 + element + 1;
		else if (numRow == 2)
			return 7 + element + 1;
		else if (numRow == 3)
			return 11 + element + 1;
		else
			return 15 + element + 1;
	}

	
	private int getRowPaddingValue(){
		int height = (int) getResources().getDimension(R.dimen.book_row_height);
		return height;
	}
	/**
	 * caculate size of screen
	 * 
	 * @return
	 */
	private CaculateScreenSize sizeOfScreen() {
		return new CaculateScreenSize(CategoryActivity.this);
	}
	
	public int convertDpToPixel(float dp) {
		DisplayMetrics metrics = getResources().getDisplayMetrics();
		float px = dp * (metrics.densityDpi / 160f);
		return (int) px;
	}

	private int heightStatusBar() {
		DisplayMetrics displayMetrics = new DisplayMetrics();
		((WindowManager) getSystemService(Context.WINDOW_SERVICE))
				.getDefaultDisplay().getMetrics(displayMetrics);

		int statusBarHeight;

		switch (displayMetrics.densityDpi) {
		case DisplayMetrics.DENSITY_HIGH:
			statusBarHeight = HIGH_DPI_STATUS_BAR_HEIGHT;
			break;
		case DisplayMetrics.DENSITY_MEDIUM:
			statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
			break;
		case DisplayMetrics.DENSITY_LOW:
			statusBarHeight = LOW_DPI_STATUS_BAR_HEIGHT;
			break;
		default:
			statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
		}
		return statusBarHeight;
	}

	/**
	 * Async task to load the data from server
	 * 
	 * @author Hoang
	 * 
	 */
	private class SyncData extends AsyncTask<String, Void, String> {

		@Override
		protected void onPreExecute() {
			// set the progress bar view
			refreshMenuItem.setActionView(R.layout.action_progressbar);
			refreshMenuItem.expandActionView();
		}

		@Override
		protected String doInBackground(String... params) {
			// TODO Auto-generated method stub
			try {
				Thread.sleep(1000);
				storeAllBooks();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			refreshMenuItem.collapseActionView();
			// remove the progress bar view
			refreshMenuItem.setActionView(null);
			
			runOnUiThread(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					
					
					if(countNewBooks == 0){
						Toast.makeText(getApplicationContext(), "No new book" , Toast.LENGTH_SHORT).show();
					} else {
						// get all book in database
						files = dataBaseHandler.getAllBooks();
						addElement(files.size());
						Toast.makeText(getApplicationContext(), countNewBooks + "new books was updated" , Toast.LENGTH_SHORT).show();
					}
				}
			});
		}

	}

	/**
	 * get path of directory
	 */
	private File getExternalSDCard() {
		Map<String, File> externalLocations = ExternalStorage
				.getAllStorageLocations();
		// File sdCard = externalLocations.get(ExternalStorage.SD_CARD);
		File externalSdCard = externalLocations
				.get(ExternalStorage.EXTERNAL_SD_CARD);
		return externalSdCard;
	}

	private void makeDirectoryOnExternalSDCard() {
		File directory = new File(getExternalSDCard() + File.separator
				+ DIRECTORY_DATA);
		if (!directory.exists() && !directory.isDirectory()) {
			if (directory.mkdirs()) {
				Log.i("CreateDir", "App dir created");
			} else {
				Log.w("CreateDir", "Unable to create app dir!");
			}
		} else {
			Log.i("CreateDir", "App dir already exists");
		}
	}

	/**
	 * get all dict info in sdcard
	 */
	private List<File> getAllDictOnExternalSDCard() {
		List<File> allDir = new ArrayList<File>();
		File directory = new File(getExternalSDCard() + File.separator
				+ DIRECTORY_DATA);
		File[] files = directory.listFiles();
		for (File inFile : files) {
			if (inFile.isDirectory()) {
				// is directory
				allDir.add(inFile);
			}
		}
		return allDir;
	}

	/**
	 * get all book on database
	 */
	private List<Book> getAllBooksInDatabase() {
		return dataBaseHandler.getAllBooks();
	}

	/**
	 * store all books into database
	 */
	private void storeAllBooks() {
		
		// list all books in sdexternalcard
		List<File> files = getAllDictOnExternalSDCard();
		
		// list all books in database
		List<Book> books = getAllBooksInDatabase();
		
		// list index books
		List<Integer> indexs = new ArrayList<Integer>();

		for (int i = 0; i < files.size(); i++) {
			File file = files.get(i);
			for (int j = 0; j < books.size(); j++) {
				Book book = books.get(j);
				if ((book.get_name().compareToIgnoreCase(file.getName())) == 0) {
					indexs.add(i);
					//Log.d("INDEX BOOK", String.valueOf(i));
					break;
				}
			}
		}

		// remove book existed
		Iterator<File> it = files.iterator();
		int cpt = 0;
		while (it.hasNext()) {
			it.next();
			if (indexs.contains(cpt)) {
				it.remove();
			}
			cpt++;
		}

		// save book into database
		
		countNewBooks = 0;
		for (File file : files) {
			countNewBooks++;
			String nameBook = file.getName();
			Book book = new Book(nameBook, false, file.getPath());
			dataBaseHandler.addBook(book);
		}
	}
	
	
//	private void updateStatusBook(Book book){
//		book.set_isRead(true);
//		dataBaseHandler.updateBook(book);
//	}

	@Override
	public boolean onNavigationItemSelected(int arg0, long arg1) {
		// TODO Auto-generated method stub
		return false;
	}

}
